home *** CD-ROM | disk | FTP | other *** search
- Path: news.rrz.uni-hamburg.de!rzdspc1!simmons
- From: simmons@rzdspc1.informatik.uni-hamburg.de (Geoffrey Simmons)
- Newsgroups: comp.lang.c,comp.databases,comp.unix.programmer
- Subject: Aligning struct fields with NDBM (was: Casting unsigned short ...)
- Followup-To: comp.unix.programmer,comp.databases
- Date: 8 Jan 96 15:59:55 GMT
- Organization: University of Hamburg -- Germany
- Message-ID: <simmons.821116795@rzdspc1>
- References: <simmons.820857453@rzdspc1>
- NNTP-Posting-Host: rzdspc1.informatik.uni-hamburg.de
-
- Thanks to everyone who responded publicly and privately to my post
- "Casting unsigned short as unsigned int -> Bus error" on comp.lang.c
- and gnu.gcc.help. As it turns out, my problem has nothing to do with
- the business about casting, and I suspect it has to do with aligning
- the struct fields of data fetched by the Unix NDBM database library.
- Thus it is probably not a C language problem, which is why I've the changed
- the Subject:, Newsgroups:, and Followup-To: lines.
-
- Recapping the problem (this is with GCC 2.7.2 on a Sparcstation running
- SunOS 4.1.4): I am using NDBM to fetch data for a struct whose fields are
- declared as follows. There's no error fetching the data or allocating
- memory for the struct:
-
- #include <ndbm.h>
- typedef struct {
- char str1[10];
- char str2[10];
- unsigned char c;
- unsigned short short1;
- unsigned short short2;
- time_t mytime;
- } RecType;
-
- RecType *MyRec;
- datum aKey, theDatum;
- char key[] = "theKey";
-
- aKey.dptr = &key[0];
- aKey.dsize = strlen(key) + 1;
- theDatum = dbm_fetch(dataFile, aKey);
- if (theDatum.dptr == NULL)
- {
- fprintf(stderr, "Data not found\n");
- exit(1); /* No error here */
- }
- if ((MyRec = (RecType *) malloc(theDatum.dsize)) == NULL)
- {
- fprintf(stderr, "Error allocting memory\n");
- exit(1); /* No error here */
- }
- MyRec = (RecType *) theDatum.dptr;
-
- At this point I can use the debugger (GDB 4.15.1) to examine all the data
- pointed to by MyRec, and see everything that I expect in all of the struct
- fields:
-
- (gdb) print *MyRec
- $1 = {short1 = 1000, short2 = 1000, c = 75 'K',
- mytime = 289104235, str1 = "String1\000\000\000",
- str2 = "String2\000\000\000"}
- (gdb) print MyRec->short1
- $2 = 1000
-
- I can also print the character-type fields using printf without problems:
-
- printf("str1 = %s\n", MyRec->str1);
- printf("str2 = %s\n", MyRec->str2);
- printf("c = %c\n", MyRec->c); /* No problem */
-
- But when I try to dereference any of the integer-type members, I get bus
- errors:
-
- unsigned short myshort;
-
- myshort = MyRec->short1; /* Bus error! */
- myshort = MyRec->short2; /* Bus error! */
- printf("mytime = %ul\n", MyRec->mytime); /* Bus error! */
-
- I conclude from all this that memory allocation for the struct is not the
- problem, but suspect that the NDBM fetch is not aligning data in memory
- properly (there are warnings about this in the comp.lang.c FAQ and the
- free-databases FAQ).
-
- I've tried some hacks like using the offsetof() macro to access the
- problematic fields as described in the C-faq, and even reordering the
- fields in the struct declaration, but get the same problem every time.
-
- On the advice of some respondents to my last post, I have added
- printf("%x\n", MyRec); to the program after each reference in which MyRec
- is involved (SunOS lets you do that). It doesn't show the address changing
- anywhere, so it doesn't appear that the pointer is being stomped on. It
- *does* show odd-numbered addresses, which some other respondents also
- suggested as a cause of the problem. But if that is the problem, why would
- I be able to access the character data, but not the integer data? And what
- would cause malloc() to allocate an illegal address in the first place?
-
- It puzzles me that the debugger can dereference all these fields without
- any of the problems that the running program has. As someone pointed out,
- memory is different when the debugger's in there with the program. The
- debugger does, however, encounter the SIGBUS error when the program reaches
- the troublesome line, even though the debugger itself has no problem
- accessing the data that the program crashes on. I still find this very
- strange.
-
- Is this a well-known problem with NDBM, with a well-known solution? I sure
- hope so.
-
- Thanks,
- Geoff
- --
- Geoffrey Simmons | simmons@informatik.uni-hamburg.de | "Insert wise
- University of Hamburg | Phone: (++49 40) 54715-381 | and witty
- Vogt-Koelln-Str. 30 | Fax: (++49 40) 54715-385 | quotation
- D-22527 Hamburg, Germany | | here."
-